package com.libre.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.libre.auth.entity.Depart;
import com.libre.auth.mapper.DepartMapper;
import com.libre.auth.service.DepartService;
import com.libre.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
* @description   部门
* @author        庞留杰
* @date          2021/12/20 20:09
* @version       V1.0
**/
@Transactional
@Slf4j
@Service
public class DepartServiceImpl extends ServiceImpl<DepartMapper, Depart> implements DepartService {

    @Override
    public IPage<Depart> findPage(Page initMpPage, Depart depart) {
        QueryWrapper<Depart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete","0");
        return this.page(initMpPage,queryWrapper);
    }

    @Override
    public List<Depart> findList(Depart depart) {
        QueryWrapper<Depart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete","0");
        List<Depart> list = this.list(queryWrapper);
        return list;
    }

    @Override
    public Depart findById(String id) {
        return this.getById(id);
    }

    @Override
    public boolean add(Depart depart) {
        return this.save(depart);
    }

    @Override
    public boolean update(Depart depart) {
        return this.updateById(depart);
    }

    @Override
    public boolean delete(String id) {
        Depart depart = new Depart();
        depart.setId(id);
        depart.setIsDelete("1");
        return this.updateById(depart);
    }

    @Override
    public List<Depart> departTree(Depart depart) {
        String departName = depart.getName();
        QueryWrapper<Depart> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("sort");
        queryWrapper.eq("is_delete", "0");
        List<Depart> departList = this.list(queryWrapper);
        departList.forEach(it-> it.setTitle(it.getName()));
        List<Depart> departs = iterateMenus(departList, "0", departName);
        return departs;
    }

    /**
     *多级部门查询方法
     * @param pid 父类id
     * @return
     */
    public List<Depart> iterateMenus(List<Depart> departList, String pid, String departName) {
        List<Depart> parents = departList.stream().filter(it -> pid.equals(it.getPid())).collect(Collectors.toList());
        Iterator<Depart> iterator = parents.iterator();
        while (iterator.hasNext()) {
            Depart depart = iterator.next();
            if (StringUtil.isNotEmpty(departName) && !isSelfAndChildrenByName(departList, depart, departName)) {
                iterator.remove();//移除
            }
            //获取部门的id
            String departId = depart.getId();
            if (isHasChildren(departList, departId)) {
                List<Depart> childrens = iterateMenus(departList, departId, departName);
                depart.setChildren(childrens);
            }
        }
        return parents;
    }

    // 判断是否还有子级
    public boolean isHasChildren(List<Depart> departList, String id) {
        return departList.stream().filter(it -> id.equals(it.getPid())).findFirst().isPresent();
    }

    // 判断自己和子级中是否包含这个部门名称（模糊查询）
    public boolean isSelfAndChildrenByName(List<Depart> departList, Depart parent, String departName) {
        boolean isContain = parent.getName().contains(departName);
        isContain = isChildrenContain(departList, parent.getId(), departName, isContain);
        return isContain;
    }

    public boolean isChildrenContain(List<Depart> departList, String pId, String departName, boolean isContain) {
        if (!isContain) {//自己不包含，继续查
            List<Depart> childrens = departList.stream().filter(it -> it.getPid().equals(pId)).collect(Collectors.toList());//子级
            for (Depart children : childrens) {
                isContain = children.getName().contains(departName);
                if (isContain) {
                    break;
                }
            }
            if (!isContain) {//子级均不包含,继续
                for (Depart children : childrens) {
                    isContain = isChildrenContain(departList, children.getId(), departName, isContain);
                    if (isContain) {
                        break;
                    }
                }
            }
        }
        return isContain;
    }
}
